 /**
 * 
 */
package es.uab.es2.TimeTracker.nucli;



import java.util.Date;
import java.util.Observable;
import java.util.Observer;
import org.apache.log4j.Logger;





/** Classe encarregada de contenir una fracci� de temps cronometrada de la tasca 
 * en un moment donat. L'interval consta de la diferencia d'una
 * <code> data inicial}</code>, instant en que comencem a cronometrar 
 * una tasca, i una  <code>data final</code>, instant en
 * que parem de cronometrar la tasca.  aquesta diferencia la tenim 
 * localitzada a l'atribut <code>duraci�</code>.
 * @author Jes�s Berm�dez, Ricard Figueras i Abel Rodr�guez
 * @version 30-mar�
 *  
 * 
 */
public class Interval  implements Observer {

 //********************** Atributs **********************
    
    /**
     * Tipus {@link Tasca}.
     * La seva funci� es indicar qui es el pare de l'interval
     * @uml.property  name="tascaPare"
     * @uml.associationEnd  multiplicity="(1 1)" 
     * inverse="intervals:es.uab.es2.TimeTracker.nucli.Tasca"
     */
    private Tasca tascaPare = null;   
    /**
     * Visualitzar  la sortida per
     *  consola del contingut dels logger.debug .
     * @uml.property  name="logger
     */
    //private Static Logger
   private static Logger logger = Logger.getLogger(Interval.class);
   
   
   /**
    * Funcionalitat: evitar el problema del magin number 
    * al checkstyle.
    */
   private static final int DOS_SEGONS = 2000; 
   
   
    /**
     * Identificador num�ric del interval, aquest identificador �s 
     * �nic per a cada objecte {@link Interval}.
     * @uml.property  name="id"
     */
    private int id = 0;
    
    /**
     * Nom identificador del {@link Interval}, no �s obligatori asignar-li 
     * valor a aquest atribut.
     * @uml.property  name="nombre"
     */
    private String nombre = new java.lang.String();
    

    /**Petit text descriptiu del {@link Interval}, no �s nessesari assignar-li 
     * valor a aquest atribut.
     * @uml.property  name="descripcio"
     */
    private String descripcio = new java.lang.String();
    
    /**
     * Captura la data en el moment que comencem a 
     * cronometrar (es referencia aquest objecte en els observers
     * de la classe {@link Rellotge}).
     * @uml.property  name="dataInici"
     */
    private Date dataInici;
    
   
    
    /**
     * Captura la data en el moment de finalitzar 
     * la cronometrada, aquest {@link Interval} deixa de ser observador
     * del Rellotge.
     * @uml.property  name="dataFi"
     */
    private Date dataFi;
    
    
    
    /**
     * Registra la diferencia de temps entre la {@link dataFi} 
     *  y la {@link dataInici}. La unitat de temps
     * d'aquest atibut en el milisegon 1s/1000.
     * @uml.property  name="durada"
     */
    private long durada = 0;
    

    //********************** Constructor **********************
    
    /**
     * Realitzaci� de la contrucci� del objecte {@link Interval}
     * Assignaci� de valors en les variables de la clase i
     * aquest{@link Interval} es introduit en un arrayList 
     * de la {@link tascaPare}.
     * @param nom   nom de l'interval a crear per el constructor
     * @param desc  una breu descripcio informativa sobre el interval
     * @param pare  Objecte Tasca asignat per ser pare del interval.
     */
    public Interval(final String nom, final String desc, final Tasca pare) {
        Identificador iden = Identificador.getInstancia();
    this.tascaPare = pare;
    this.nombre = nom;
    this.descripcio = desc;
    this.dataInici = Rellotge.getDataInicial();
    this.id = iden.getContador();
    tascaPare.getIntervals().add(this); 
    }
   
//********************** Getters & Setters **********************

	/**
	 * Getter of the property <tt>tascaPare</tt> Agafa el objecte Tasca
	 *  pare del interval actual.
	 * @return  Returns the tascaPare.
	 * @uml.property  name="tascaPare"
	 */
	public final Tasca getTascaPare() {
		return tascaPare;
	}

	/**
	 * Setter of the property <tt>tascaPare</tt> Asigna al interval 
	 * una Tasca pare que l'ha creat.
	 * @param tascaPare  The tascaPare to set.
	 * @uml.property  name="tascaPare"
	 */
	public final void setTascaPare(final Tasca tTascaPare) {
		this.tascaPare = tTascaPare;
	}

		/**
		 * Getter of the property <tt>id</tt> recull el identificador .
		 * @return  Returns the id.
		 * @uml.property  name="id"
		 */
		public final int getId() {
			return id;
		}

		/**
		 * Setter of the property <tt>id</tt>.
		 * @param id  The id to set.
		 * @uml.property  name="id"
	
		 */
		public final void setId(final int iId) {
			this.id = iId;
		}

		/**
		 * Getter of the property <tt>nombre</tt>.
		 * @return  Returns the nombre.
		 * @uml.property  name="nombre"
		 */
		public final String getNombre() {
			return nombre;
		}

		/**
		 * Setter of the property <tt>nombre</tt>.
		 * @param nombre  The nombre to set.
		 * @uml.property  name="nombre"
		 */
		public final void setNombre(final String sNombre) {
			this.nombre = sNombre;
		}

		/**
		 * Getter of the property <tt>descripcio</tt>.
		 * @return  Returns the descripcio.
		 * @uml.property  name="descripcio"
		 */
		public final String getDescripcio() {
			return descripcio;
		}

		/**
		 * Setter of the property <tt>descripcio</tt>.
		 * @param descripcio  The descripcio to set.
		 * @uml.property  name="descripcio"
		 */
		public final void setDescripcio(final String sDescripcio) {
			this.descripcio = sDescripcio;
		}

		/**
		 * Getter of the property <tt>data_inici</tt>.
		 * @return  Returns the data_inici.
		 * @uml.property  name="data_inici"
		 */
		public final Date getDataInici() {
			return dataInici;
		}

		/**
		 * Setter of the property <tt>data_inici</tt>.
		 * @param data_inici  The data_inici to set.
		 * @uml.property  name="data_inici"
		 */
		public final void setDataInici(final Date dDataInici) {
			this.dataInici = dDataInici;
		}

		/**
		 * Getter of the property <tt>dataFi</tt>.
		 * @return  Returns the dataFi.
		 * @uml.property  name="dataFi"
		 */
		public final Date getDataFi() {
			return dataFi;
		}

		/**
		 * Setter of the property <tt>dataFi</tt>.
		 * @param dataFi  The data_fi to set.
		 * @uml.property  name="dataFi"
		 */
		public final void setDataFi(final Date dDataFi) {
			this.dataFi = dDataFi;
		}
	
		/**
		 * Getter of the property <tt>durada</tt>.
		 * @return  Returns the durada.
		 * @uml.property  name="durada"
		 */
		public final long getDurada() {
			return durada;
		}

		/**
		 * Setter of the property <tt>durada</tt>.
		 * @param durada  The durada to set.
		 * @uml.property  name="durada"
		 */
		public final void setDurada(final long lDurada) {
			this.durada = lDurada;
		}
			
//********************** Metodes Implementacio **********************
				
		/**
		 * Encarregat d'informar els observadors 
		 * que el {@link Rellotge} ha cambiat 
		 * llavors {@link Interval} actualitza 
		 * la {@link dataFi} i {@link durada} d'ell mateix
		 * i de les tasques y projectes pares .
		 */
	    @Override
	    public final void update(final Observable observable, 
	            final Object data) {
	        // TODO Auto-generated method stub       
	        
	       this.repartirDataFinal(Rellotge.getDataActual());
	        this.repartirDurada(Rellotge.getIntervaloMs());
	    }
	            
	    /**
	     * Encarregat de mostrar per consola, 
	     * atributs d'aquest {@link Interval} nom�s 
	     * es utilitzat en cas de prova per obtindre 
	     * informaci�.
	    */
	     public final void mostrarInterval() {
	     logger.debug(this.nombre + "\t" + "Data inici:" + this.dataInici
	      + "\t" + "Data final:" + this.dataFi + "durada:" + this.durada 
	      + "segons");
	         
	         }

			
			/**
			 * Asigna data final a les activitats antesesores
			 * d'aquest interval.
			 * @param dataFinalProv
			 */
			public final void repartirDataFinal(final Date dataFinalProv) {
			    Activitat activitatBusca = this.tascaPare;
	            while (activitatBusca != null) {
	                this.setDataFi(dataFinalProv);
	                activitatBusca.setDataFinal(this.dataFi);
	                activitatBusca = activitatBusca.getProjectePare();
	            }  
	           
			}

			  /**
             * Asigna  durada a les activitats antesesores
             * d'aquest interval.
             * 
             */
            public final void repartirDurada(long duradaProvisional) {
                long sumaDurada = 0;
                Activitat activitatBusca = this.tascaPare; 
                    while (activitatBusca != null) {
                        sumaDurada = activitatBusca.getDurada() + duradaProvisional;
                        activitatBusca.setDurada(sumaDurada);
                        activitatBusca = activitatBusca.getProjectePare();
                    }  
                    this.durada = duradaProvisional;
                
              
            }



}
